package org.example.service;

import org.example.entity.Scene;
import org.example.entity.SceneDevice;
import org.example.entity.Device;
import org.example.repository.SceneRepository;
import org.example.repository.SceneDeviceRepository;
import org.example.repository.DeviceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * 场景服务类
 */
@Service
@Transactional
public class SceneService {
    
    @Autowired
    private SceneRepository sceneRepository;
    
    @Autowired
    private SceneDeviceRepository sceneDeviceRepository;
    
    @Autowired
    private DeviceRepository deviceRepository;
    
    /**
     * 创建场景
     */
    public Scene createScene(Scene scene) {
        // 检查场景名称是否已存在
        if (sceneRepository.findByUserIdAndName(scene.getUserId(), scene.getName()).isPresent()) {
            throw new RuntimeException("场景名称已存在");
        }
        
        return sceneRepository.save(scene);
    }
    
    /**
     * 根据ID查找场景
     */
    @Transactional(readOnly = true)
    public Optional<Scene> findById(Long id) {
        return sceneRepository.findById(id);
    }
    
    /**
     * 根据用户ID查找场景
     */
    @Transactional(readOnly = true)
    public List<Scene> findByUserId(Long userId) {
        return sceneRepository.findByUserId(userId);
    }
    
    /**
     * 根据激活状态查找场景
     */
    @Transactional(readOnly = true)
    public List<Scene> findByUserIdAndIsActive(Long userId, Integer isActive) {
        return sceneRepository.findByUserIdAndIsActive(userId, isActive);
    }
    
    /**
     * 根据场景名称搜索
     */
    @Transactional(readOnly = true)
    public List<Scene> searchScenesByName(Long userId, String name) {
        return sceneRepository.findByUserIdAndNameContaining(userId, name);
    }
    
    /**
     * 更新场景信息
     */
    public Scene updateScene(Scene scene) {
        Scene existingScene = sceneRepository.findById(scene.getId())
                .orElseThrow(() -> new RuntimeException("场景不存在"));
        
        if (scene.getName() != null) {
            // 检查新名称是否与其他场景冲突
            Optional<Scene> conflictScene = sceneRepository.findByUserIdAndName(existingScene.getUserId(), scene.getName());
            if (conflictScene.isPresent() && !conflictScene.get().getId().equals(scene.getId())) {
                throw new RuntimeException("场景名称已存在");
            }
            existingScene.setName(scene.getName());
        }
        if (scene.getDescription() != null) {
            existingScene.setDescription(scene.getDescription());
        }
        
        return sceneRepository.save(existingScene);
    }
    
    /**
     * 激活/停用场景
     */
    public Scene updateSceneStatus(Long sceneId, Integer isActive) {
        Scene scene = sceneRepository.findById(sceneId)
                .orElseThrow(() -> new RuntimeException("场景不存在"));
        
        scene.setIsActive(isActive);
        return sceneRepository.save(scene);
    }
    
    /**
     * 执行场景
     */
    public void executeScene(Long sceneId, Long userId) {
        Scene scene = sceneRepository.findById(sceneId)
                .orElseThrow(() -> new RuntimeException("场景不存在"));
        
        // 检查场景是否属于该用户
        if (!scene.getUserId().equals(userId)) {
            throw new RuntimeException("无权限执行该场景");
        }
        
        // 获取场景中的所有设备
        List<SceneDevice> sceneDevices = sceneDeviceRepository.findBySceneId(sceneId);
        
        // 执行每个设备的设置
        for (SceneDevice sceneDevice : sceneDevices) {
            Device device = deviceRepository.findById(sceneDevice.getDeviceId())
                    .orElseThrow(() -> new RuntimeException("设备不存在"));
            
            // 更新设备状态
            if (sceneDevice.getDeviceStatus() != null) {
                device.setStatus(sceneDevice.getDeviceStatus());
            }
            
            // 更新设备属性
            if (sceneDevice.getDeviceProperties() != null) {
                device.setProperties(sceneDevice.getDeviceProperties());
            }
            
            deviceRepository.save(device);
        }
    }
    
    /**
     * 添加设备到场景
     */
    public SceneDevice addDeviceToScene(Long sceneId, Long deviceId, Integer deviceStatus, String deviceProperties) {
        Scene scene = sceneRepository.findById(sceneId)
                .orElseThrow(() -> new RuntimeException("场景不存在"));
        
        Device device = deviceRepository.findById(deviceId)
                .orElseThrow(() -> new RuntimeException("设备不存在"));
        
        // 检查设备是否属于场景的用户
        if (!device.getUserId().equals(scene.getUserId())) {
            throw new RuntimeException("设备不属于该用户");
        }
        
        // 检查设备是否已在场景中
        if (sceneDeviceRepository.findBySceneIdAndDeviceId(sceneId, deviceId).isPresent()) {
            throw new RuntimeException("设备已在场景中");
        }
        
        SceneDevice sceneDevice = new SceneDevice(sceneId, deviceId, deviceStatus, deviceProperties);
        return sceneDeviceRepository.save(sceneDevice);
    }
    
    /**
     * 从场景中移除设备
     */
    public void removeDeviceFromScene(Long sceneId, Long deviceId) {
        SceneDevice sceneDevice = sceneDeviceRepository.findBySceneIdAndDeviceId(sceneId, deviceId)
                .orElseThrow(() -> new RuntimeException("设备不在场景中"));
        
        sceneDeviceRepository.delete(sceneDevice);
    }
    
    /**
     * 获取场景中的设备
     */
    @Transactional(readOnly = true)
    public List<SceneDevice> getSceneDevices(Long sceneId) {
        return sceneDeviceRepository.findBySceneId(sceneId);
    }
    
    /**
     * 更新场景设备设置
     */
    public SceneDevice updateSceneDevice(Long sceneId, Long deviceId, Integer deviceStatus, String deviceProperties) {
        SceneDevice sceneDevice = sceneDeviceRepository.findBySceneIdAndDeviceId(sceneId, deviceId)
                .orElseThrow(() -> new RuntimeException("设备不在场景中"));
        
        if (deviceStatus != null) {
            sceneDevice.setDeviceStatus(deviceStatus);
        }
        if (deviceProperties != null) {
            sceneDevice.setDeviceProperties(deviceProperties);
        }
        
        return sceneDeviceRepository.save(sceneDevice);
    }
    
    /**
     * 统计用户场景数量
     */
    @Transactional(readOnly = true)
    public long countScenesByUserId(Long userId) {
        return sceneRepository.countByUserId(userId);
    }
    
    /**
     * 统计激活场景数量
     */
    @Transactional(readOnly = true)
    public long countActiveScenesByUserId(Long userId) {
        return sceneRepository.countActiveScenesByUserId(userId);
    }
    
    /**
     * 删除场景
     */
    public void deleteScene(Long sceneId) {
        if (!sceneRepository.existsById(sceneId)) {
            throw new RuntimeException("场景不存在");
        }
        sceneRepository.deleteById(sceneId);
    }
    
    /**
     * 统计所有场景数量
     */
    @Transactional(readOnly = true)
    public long countAllScenes() {
        return sceneRepository.count();
    }
    
    /**
     * 统计激活场景数量
     */
    @Transactional(readOnly = true)
    public long countActiveScenes() {
        return sceneRepository.countByStatus(1);
    }
}
